#include "clib_command.h"
#include <stdlib.h>
#include "clib_log.h"


#define CLIB_ARGS_DEAL_WITH(args)   (args->argc - args->deal)


i32_t
clib_pars_config(clib_config_t *conf, clib_conf_t *args) 
{
    if(!conf || !args) {
        return 0;
    }

    if(conf->type != clib_config_type_str) {
        if(clib_config_item_to_string(conf) < 0) {
            return 0;
        }
    }

    args->argv[0] = conf->key;
    args->argv[1] = conf->value.ptr;
    args->argc    = 2;
    
    return args->argc;
}

i32_t
clib_pars_cmd_line(u08_t *line, clib_conf_t *args)
{
    i32_t  argc = 0;
    u08_t *argv;
    i32_t  type = 0;
    u08_t *sign = line;
    
    while (*sign)
    {
        while (*sign &&  *sign == ' ') {
            sign++;
        }
        
        if(!*sign) {
            break;
        }

        argv = sign;

        args->argv[argc++] = argv;

        while(*sign &&  *sign != ' ') {
            sign++;
        }
       
        if(!*sign) {
            break;
        }

        *sign = 0;

        sign++; 
    }

    return argc;
}

i32_t
clib_set_i08_type(clib_conf_t *args, clib_command_t *cmd, void *conf)
{
    if(memcmp(args->argv[args->deal],cmd->name,strlen(cmd->name)) \
              || CLIB_ARGS_DEAL_WITH(args) != 2 || !conf)
    {
        clib_log_debug("config name: %s cmd name: %s conf: %p\n", args->argv[args->deal], cmd->name, conf);
        return rn_error;
    }

    i08_t *n = (i08_t*)((char*)(conf) + cmd->offset);
    *n = (i08_t)atol(args->argv[args->deal + 1]);
    
    args->deal += 2;

    return rn_ok;
}

i32_t
clib_set_u08_type(clib_conf_t *args, clib_command_t *cmd, void *conf)
{
    if(memcmp(args->argv[args->deal],cmd->name,strlen(cmd->name)) \
              || CLIB_ARGS_DEAL_WITH(args) != 2 || !conf)
    {
        clib_log_debug("config name: %s cmd name: %s conf: %p\n", args->argv[args->deal], cmd->name, conf);
        return rn_error;
    }

    u08_t *n = (u08_t*)((char*)(conf) + cmd->offset);
    *n = (u08_t)atol(args->argv[args->deal + 1]);
    
    args->deal += 2;

    return rn_ok;
}

i32_t
clib_set_i16_type(clib_conf_t *args, clib_command_t *cmd, void *conf)
{
    if(memcmp(args->argv[args->deal],cmd->name,strlen(cmd->name)) \
              || CLIB_ARGS_DEAL_WITH(args) != 2 || !conf)
    {
        clib_log_debug("config name: %s cmd name: %s conf: %p\n", args->argv[args->deal], cmd->name, conf);
        return rn_error;
    }

    i16_t *n = (i16_t*)((char*)(conf) + cmd->offset);
    *n = (i16_t)atol(args->argv[args->deal + 1]);
    
    args->deal += 2;

    return rn_ok;
}

i32_t
clib_set_u16_type(clib_conf_t *args, clib_command_t *cmd, void *conf)
{
    if(memcmp(args->argv[args->deal],cmd->name,strlen(cmd->name)) \
              || CLIB_ARGS_DEAL_WITH(args) != 2 || !conf)
    {
        clib_log_debug("config name: %s cmd name: %s conf: %p\n", args->argv[args->deal], cmd->name, conf);
        return rn_error;
    }

    u16_t *n = (u16_t*)((char*)(conf) + cmd->offset);
    *n = (u16_t)atol(args->argv[args->deal + 1]);
    
    args->deal += 2;

    return rn_ok;
}

i32_t
clib_set_i32_type(clib_conf_t *args, clib_command_t *cmd, void *conf)
{
    if(memcmp(args->argv[args->deal],cmd->name,strlen(cmd->name)) \
              || CLIB_ARGS_DEAL_WITH(args) != 2 || !conf)
    {
        clib_log_debug("config name: %s cmd name: %s conf: %p\n", args->argv[args->deal], cmd->name, conf);
        return rn_error;
    }

    i32_t *n = (i32_t*)((char*)(conf) + cmd->offset);
    *n = (i32_t)atol(args->argv[args->deal + 1]);
    
    args->deal += 2;

    return rn_ok;
}

i32_t
clib_set_u32_type(clib_conf_t *args, clib_command_t *cmd, void *conf)
{
    if(memcmp(args->argv[args->deal],cmd->name,strlen(cmd->name)) \
              || CLIB_ARGS_DEAL_WITH(args) != 2 || !conf)
    {
        clib_log_debug("config name: %s cmd name: %s conf: %p\n", args->argv[args->deal], cmd->name, conf);
        return rn_error;
    }

    u32_t *n = (u32_t*)((char*)(conf) + cmd->offset);
    *n = (u32_t)strtoul(args->argv[args->deal + 1], NULL, 10);
    
    args->deal += 2;

    return rn_ok;
}

i32_t
clib_set_i64_type(clib_conf_t *args, clib_command_t *cmd, void *conf)
{
    if(memcmp(args->argv[args->deal],cmd->name,strlen(cmd->name)) \
              || CLIB_ARGS_DEAL_WITH(args) != 2 || !conf)
    {
        clib_log_debug("config name: %s cmd name: %s conf: %p\n", args->argv[args->deal], cmd->name, conf);
        return rn_error;
    }

    i64_t *n = (i64_t*)((char*)(conf) + cmd->offset);
    *n = (i64_t)strtoll(args->argv[args->deal + 1], NULL, 10);
    
    args->deal += 2;

    return rn_ok;
}

i32_t
clib_set_u64_type(clib_conf_t *args, clib_command_t *cmd, void *conf)
{
    if(memcmp(args->argv[args->deal],cmd->name,strlen(cmd->name)) \
              || CLIB_ARGS_DEAL_WITH(args) != 2 || !conf)
    {
        clib_log_debug("config name: %s cmd name: %s conf: %p\n", args->argv[args->deal], cmd->name, conf);
        return rn_error;
    }

    u64_t *n = (u64_t*)((char*)(conf) + cmd->offset);
    *n = (u64_t)strtoull(args->argv[args->deal + 1], NULL, 10);
    
    args->deal += 2;

    return rn_ok;
}

i32_t
clib_set_str_type(clib_conf_t *args, clib_command_t *cmd, void *conf)
{
    if(memcmp(args->argv[args->deal],cmd->name,strlen(cmd->name)) \
              || CLIB_ARGS_DEAL_WITH(args) != 2 || !conf)
    {
        clib_log_debug("config name: %s cmd name: %s conf: %p\n", args->argv[args->deal], cmd->name, conf);
        return rn_error;
    }
    i32_t len = strlen(args->argv[args->deal]);

    u08_t *buf = (u08_t*)((char*)(conf) + cmd->offset);
    
    if(len >= cmd->size) {
        clib_log_debug("config name: %s cmd name: %s buffer more than config cache\n", args->argv[args->deal], cmd->name);
        return rn_error;
    } else {
        memcpy(buf, args->argv[args->deal], len + 1);
    }
    args->deal += 2;

    return rn_ok;
}
